import { _decorator, Button, Component, Label, Node, ProgressBar, Root, Sprite, Toggle, Tween, tween, UIOpacity, UITransform } from 'cc';
import { UIBase } from './UIBase';
import GameData from '../data/GameData';
import { SkillItem } from './item/SkillItem';
import { UIStage } from './UIStage';
import { AudioManager } from '../game/AudioManager';
import Utils from '../utils/Utils';
const { ccclass, property } = _decorator;

@ccclass('UISkill')
export class UISkill extends UIBase {
    static instance: UISkill = null;

    @property(Label) skillRemain: Label = null;
    @property(Label) fightingPower: Label = null;

    // 下一步
    @property(Button) btnNext: Button = null;
    @property(Node) nextHand: Node = null!;

    // 技能分配
    @property({ type: SkillItem, displayName: "唱歌技能点" }) skill_sing: SkillItem;
    @property({ type: SkillItem, displayName: "跳舞技能点" }) skill_dance: SkillItem;
    @property({ type: SkillItem, displayName: "台风技能点" }) skill_stage: SkillItem;

    @property({ type: Node, displayName: "唱歌技能提示" }) singHandTips: Node = null!;
    @property({ type: Node, displayName: "跳舞技能提示" }) danceHandTips: Node = null!;
    @property({ type: Node, displayName: "台风技能提示" }) stageHandTips: Node = null!;

    // PK对象属性
    @property(ProgressBar) pk_sing: ProgressBar = null!;
    @property(ProgressBar) pk_dance: ProgressBar = null!;
    @property(ProgressBar) pk_stage: ProgressBar = null!;
    @property(Node) dummy: Node = null!;

    // 玩家属性
    @property(ProgressBar) player_sing: ProgressBar = null!;
    @property(ProgressBar) player_dance: ProgressBar = null!;
    @property(ProgressBar) player_stage: ProgressBar = null!;

    // 地图选择
    @property(Toggle) tog_park: Toggle = null!;
    @property(Node) parkLight: Node = null!;
    @property(Node) parkHand: Node = null!;

    @property(Toggle) tog_bar: Toggle = null!;
    @property(Node) barLight: Node = null!;
    @property(Node) barHand: Node = null!;

    @property(Toggle) tog_stadium: Toggle = null!;
    @property(Node) stadiumLight: Node = null!;
    @property(Node) stadiumHand: Node = null!;

    // 遮罩
    @property(Node) skillMask: Node = null!;
    @property(Node) mapMask: Node = null!;
    @property(Node) leftPanel: Node = null!;



    private sprite: Sprite = null;
    private idleTimerId: number = 0;
    private idleTimeoutMs: number = 5000; // 5s
    private parkHandOpacity: UIOpacity | null = null;
    private barHandOpacity: UIOpacity | null = null;
    private stadiumHandOpacity: UIOpacity | null = null;
    private mapHandTween: Tween | null = null;

    onLoad() {
        super.onLoad();
        UISkill.instance = this;
        this.sprite = this.btnNext.node.getComponent(Sprite);
        this.btnNext.node.on(Button.EventType.CLICK, this.onNextClikced, this);
        this.initUI();
    }

    onShow(): void {
        super.onShow();
        tween(this.pk_sing)
            .call(() => { this.pk_sing.progress = 0; })
            .to(1, { progress: 0.8 }, { easing: 'quadOut' })
            .start();
        tween(this.pk_dance)
            .call(() => { this.pk_dance.progress = 0; })
            .to(1, { progress: 0.9 }, { easing: 'quadOut' })
            .start();
        tween(this.pk_stage)
            .call(() => { this.pk_stage.progress = 0; })
            .to(1, { progress: 0.8 }, { easing: 'quadOut' })
            .start();

        this.player_sing.progress = 0;
        this.player_dance.progress = 0;
        this.player_stage.progress = 0;


        // 启动闲置检测计时器
        this.startIdleTimer(0);
    }

    private initUI() {
        this.leftPanel.children.forEach((child) => { Utils.AutoScale(child); });
        Utils.AutoScale(this.dummy);
        Utils.AutoScale(this.skillRemain.node);

        // 初始化技能
        this.skill_sing.onSkillChanged = this.onSkillChanged.bind(this);
        this.skill_dance.onSkillChanged = this.onSkillChanged.bind(this);
        this.skill_stage.onSkillChanged = this.onSkillChanged.bind(this);
        this.onSkillChanged(false);

        // 初始化地图
        this.tog_park.node.on('toggle', () => this.onMapToggle(this.tog_park), this);
        this.tog_bar.node.on('toggle', () => this.onMapToggle(this.tog_bar), this);
        this.tog_stadium.node.on('toggle', () => this.onMapToggle(this.tog_stadium), this);

        // 缓存 hand 的 opacity 组件，减少每次调用时 getComponent 的开销
        this.parkHandOpacity = this.parkHand.getComponent(UIOpacity) || null;
        this.barHandOpacity = this.barHand.getComponent(UIOpacity) || null;
        this.stadiumHandOpacity = this.stadiumHand.getComponent(UIOpacity) || null;
    }

    /** 地图选择互斥逻辑 */
    private onMapToggle(selected: Toggle) {
        AudioManager.Instance.playUIClick();

        this.parkHand.active = false;
        this.barHand.active = false;
        this.stadiumHand.active = false;

        if (selected.isChecked) {
            if (selected !== this.tog_park) this.tog_park.isChecked = false;
            if (selected !== this.tog_bar) this.tog_bar.isChecked = false;
            if (selected !== this.tog_stadium) this.tog_stadium.isChecked = false;
        } else {
            if (!this.tog_park.isChecked && !this.tog_bar.isChecked && !this.tog_stadium.isChecked) {
                selected.isChecked = true;
            }
        }

        // 设置当前地图索引
        if (this.tog_park.isChecked) GameData.currentMap = 0;
        if (this.tog_bar.isChecked) GameData.currentMap = 1;
        if (this.tog_stadium.isChecked) GameData.currentMap = 2;

        // 控制高亮显示（确保只有对应的 light 被激活）
        this.parkLight.active = !!this.tog_park.isChecked;
        this.barLight.active = !!this.tog_bar.isChecked;
        this.stadiumLight.active = !!this.tog_stadium.isChecked;

        this.onSkillChanged(false);
    }



    private onNextClikced() {
        AudioManager.Instance.playUIClick();
        this.onHide();
        UIStage.instance.onShow();
        GameData.singSkillLevel = this.skill_sing.skillLevel;
        GameData.danceSkillLevel = this.skill_dance.skillLevel;
        GameData.stageSkillLevel = this.skill_stage.skillLevel;
    }

    /** 分配了技能点 */
    private onSkillChanged(showHandTips: boolean) {
        console.log(`是否显示技能分配提示:${showHandTips}`);

        // 用户有操作时重置闲置计时器
        this.resetIdleTimer();
        this.showSkillHandTips(showHandTips);
        console.log(`技能点剩余：${GameData.skillRemainNum}`);

        this.skillMask.active = GameData.skillRemainNum === 10;
        this.skillRemain.string = `${GameData.skillRemainNum}`;
        this.fightingPower.string = `${GameData.getFightingPower()}`;

        // 更新
        this.btnNext.interactable = false;
        this.sprite.grayscale = true;
        this.nextHand.active = false;
        if (GameData.skillRemainNum <= 0) {
            if (GameData.currentMap === -1) {
                this.playMapHandAnim(true);
            } else {
                this.playMapHandAnim(false);
                this.btnNext.interactable = true;
                this.sprite.grayscale = false;
                this.nextHand.active = true;
            }
        } else {
            this.playMapHandAnim(false);
        }

        if (GameData.skillRemainNum === 0 && GameData.currentMap === -1) {
            this.mapMask.active = true;
        } else {
            this.mapMask.active = false;
        }
    }

    // 闲置计时器控制：当超过 idleTimeoutMs 没有分配技能点时，显示技能提示
    private startIdleTimer(idleTime: number = this.idleTimeoutMs) {
        this.stopIdleTimer();
        this.idleTimerId = window.setTimeout(() => {
            // 如果当前还可分配技能点且未达到上限，则显示提示
            if (GameData.skillRemainNum > 0) {
                this.showSkillHandTips(true);
            }
        }, idleTime) as unknown as number;
    }

    private resetIdleTimer() {
        this.startIdleTimer();
    }

    private stopIdleTimer() {
        if (this.idleTimerId) {
            clearTimeout(this.idleTimerId);
            this.idleTimerId = 0;
        }
    }

    /** 显示技能提示 */
    private showSkillHandTips(show: boolean) {
        if (!show) {
            this.singHandTips.active = false;
            this.danceHandTips.active = false;
            this.stageHandTips.active = false;
            return;
        }

        this.singHandTips.active = false;
        this.danceHandTips.active = false;
        this.stageHandTips.active = false;
        console.log(`技能点：唱歌${this.skill_sing.skillLevel}，跳舞${this.skill_dance.skillLevel}，台风${this.skill_stage.skillLevel}`);
        if (this.skill_sing.btn_add.interactable) {
            this.singHandTips.active = true;
            this.singHandTips.angle = 0;
            Tween.stopAllByTarget(this.singHandTips);
            tween(this.singHandTips)
                .delay(0.2)
                .to(1, { angle: 30 })
                .to(1, { angle: 0 })
                .delay(0.2)
                .union()
                .repeatForever()
                .start();
            return;
        }

        if (this.skill_dance.btn_add.interactable) {
            this.danceHandTips.active = true;
            this.danceHandTips.angle = 0;
            Tween.stopAllByTarget(this.danceHandTips);
            tween(this.danceHandTips)
                .delay(0.2)
                .to(1, { angle: 30 })
                .to(1, { angle: 0 })
                .delay(0.2)
                .union()
                .repeatForever()
                .start();
            return;
        }
        if (this.skill_stage.btn_add.interactable) {
            this.stageHandTips.active = true;
            this.stageHandTips.angle = 0;
            Tween.stopAllByTarget(this.stageHandTips);
            tween(this.stageHandTips)
                .delay(0.2)
                .to(1, { angle: 30 })
                .to(1, { angle: 0 })
                .delay(0.2)
                .union()
                .repeatForever()
                .start();
            return;
        }
    }

    private playMapHandAnim(show: boolean) {
        if (!show) {
            this.stopMapHandAnim();
            return;
        }

        // 停止已有的运行 tween
        if (this.mapHandTween) {
            try { this.mapHandTween.stop(); } catch (e) {}
            this.mapHandTween = null;
        }
        Tween.stopAllByTarget(this.node);

        const sets: Array<{ node: Node, opacity: UIOpacity | null }> = [
            { node: this.parkHand, opacity: this.parkHandOpacity },
            { node: this.barHand, opacity: this.barHandOpacity },
            { node: this.stadiumHand, opacity: this.stadiumHandOpacity },
        ];

        sets.forEach(s => { s.node.active = true; if (s.opacity) s.opacity.opacity = 0; s.node.angle = 0; });

        const t1 = tween(this.parkHand)
            .call(() => { if (this.parkHandOpacity) this.parkHandOpacity.opacity = 255; })
            .to(0.5, { angle: 30 })
            .to(0.5, { angle: 0 })
            .delay(0.1)
            .call(() => { if (this.parkHandOpacity) this.parkHandOpacity.opacity = 0; });

        const t2 = tween(this.barHand)
            .call(() => { if (this.barHandOpacity) this.barHandOpacity.opacity = 255; })
            .to(0.5, { angle: 30 })
            .to(0.5, { angle: 0 })
            .delay(0.1)
            .call(() => { if (this.barHandOpacity) this.barHandOpacity.opacity = 0; });

        const t3 = tween(this.stadiumHand)
            .call(() => { if (this.stadiumHandOpacity) this.stadiumHandOpacity.opacity = 255; })
            .to(0.5, { angle: 30 })
            .to(0.5, { angle: 0 })
            .delay(0.1)
            .call(() => { if (this.stadiumHandOpacity) this.stadiumHandOpacity.opacity = 0; });

        // 保存引用，便于后续停止
        this.mapHandTween = tween(this.node)
            .sequence(t1, t2, t3)
            .union()
            .repeatForever();

        this.mapHandTween.start();
    }

    private stopMapHandAnim() {
        if (this.mapHandTween) {
            try { this.mapHandTween.stop(); } catch (e) { }
            this.mapHandTween = null;
        }
        Tween.stopAllByTarget(this.node);
        [this.parkHand, this.barHand, this.stadiumHand].forEach(n => { n.active = false; n.angle = 0; });
        if (this.parkHandOpacity) this.parkHandOpacity.opacity = 0;
        if (this.barHandOpacity) this.barHandOpacity.opacity = 0;
        if (this.stadiumHandOpacity) this.stadiumHandOpacity.opacity = 0;
    }


}